#! /usr/bin/env python
# coding=utf8
# python2.7
 
from Tkinter import *
import Tkinter as tk
import threading
from thread import *
import time
from socket import *
import socket 
import sys

HOST = socket.gethostbyname(socket.gethostname())#'127.0.0.1'
PORT = 8808
BUFSIZ = 1024
ADDR = (HOST, PORT)
class Application(tk.Frame):
    def __init__(self, master=None):
        tk.Frame.__init__(self, master)
        self.grid()
        self.createFrameTop()
        self.createFrameMiddle()
        self.createFrameBottom()
        self.flag = False
    def createFrameTop(self):
        self.frmTop = tk.LabelFrame(root, text='Top')
        self.chatText   = tk.Text(self.frmTop, height=15, width=80)
        self.chatText.tag_config('blue', foreground='blue', font=('Tempus Sans ITC',15))
        self.chatText.tag_config('red', foreground='red', font=('Tempus Sans ITC',15))
        self.chatText.tag_config('black', foreground='black', font=('Tempus Sans ITC',15))
        self.chatScl = Scrollbar(self.frmTop)
        self.chatScl['command'] = self.chatText.yview
        self.chatText['yscrollcommand']=self.chatScl.set
        self.frmTop.grid(row = 0, column = 0, sticky = 'w'+'e'+'n'+'s')
        self.chatText.grid(row = 0, column = 0, sticky = 'w'+'e'+'n'+'s')
        self.chatScl.grid(row = 0, column = 1, sticky = 'w'+'e'+'n'+'s')
    def createFrameMiddle(self):
        self.frmMiddle = tk.LabelFrame(root, text='Middle')
        self.inputText = tk.Text(self.frmMiddle, height=8, width=80)
        self.inputText.bind("<Return>", self.sendMessage)
        self.inputScl = Scrollbar(self.frmMiddle)
        self.inputScl['command'] = self.inputText.yview
        self.inputText['yscrollcommand']=self.inputScl.set
        self.frmMiddle.grid(row = 1, column = 0, sticky = 'w'+'e'+'n'+'s')
        self.inputText.grid(row = 0, column = 0, sticky = 'w'+'e'+'n'+'s')
        self.inputScl.grid(row = 0, column = 1, sticky = 'w'+'e'+'n'+'s') 
    def createFrameBottom(self):
        self.frmButton = tk.LabelFrame(root, text='Bottom')
        self.btnSend = tk.Button(self.frmButton, text='send', width=10, command=self.sendMessage)
        self.btnClose = tk.Button(self.frmButton, text='close', width=10, command=self.Close)
        self.frmButton.grid(row = 2, column = 0, ipadx=0, ipady=0, sticky = 'w'+'e'+'n'+'s')
        self.btnSend.grid(row = 0, column = 0, padx=50, pady=0, sticky = 'e')
        self.btnClose.grid(row = 0, column = 1, padx=150, pady=0, sticky = 'e')
    def sendMessage(self, event=None):#,clientlist_div={}):
        message = self.inputText.get('0.0', END)
        theTime = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) 
        self.chatText.insert(END, '服务器 ' + theTime +' 说： \n') 
        self.chatText.insert(END, '  ' + message + '\n', 'red')
        self.chatText.see(END)    
        if self.flag == True:
#             print 'clientlist:',self.clientlist.keys()
            if len(self.clientlist.keys())!=0:
                for i in self.clientlist.keys():
                    i.send(message.encode('utf8')) 
        else: 
            self.chatText.insert(END, '你还未与客户端建立连接，客户端无法接受您的消息 \n', 'red')
        self.inputText.delete(0.0, END)
    def Close(self):
        self.Close()
        sys.exit()
    def receiveMessage(self):  
        def messagehandle(clientlist,connection,address):
            while True:
                for i in range(1):#clientlist.keys():
                    try:
                        clientMsg = str(connection.recv(BUFSIZ))
                    except:
                        pass
                    if not clientMsg: 
                        continue
                    elif clientMsg == 'Y':
                        self.chatText.insert(END, '服务器端已经与客户端'+str(clientlist[connection])+'建立连接......\n')
                        connection.send(clientMsg.encode('utf8'))       
                    elif clientMsg == 'N':
                        self.chatText.insert(END, '服务器端与客户端'+str(clientlist[connection])+'连接失败......\n')
                        connection.send(clientMsg.encode('utf8')) 
                    else: 
                        theTime = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) 
                        self.chatText.insert(END, '客户端 ' +str(address[-1])+' '+ theTime +' 说： \n') 
                        self.chatText.insert(END, '  ' + str(clientMsg)+'\n', 'blue')
                        self.chatText.see(END)
                        for i in clientlist.keys():
#                             try:
                            i.send((clientMsg+' , '+str(address[1])).encode('utf8'))
#                             except:
#                                 pass    
        self.ServerSock = socket.socket(AF_INET, SOCK_STREAM)        #SOCK_STREAM(流套接字)和SOCK_DGRAM(数据报套接字),(套接字socket分为Unix socket和Internet socket)
        self.ServerSock.bind(ADDR)
        self.ServerSock.listen(5)
        self.chatText.insert(END, '服务器已经就绪...... \n')
        self.count=0
        self.clientlist={}
        while True:
            connection,address = self.ServerSock.accept()
            if connection and address:
                if connection not in self.clientlist.keys():
                    self.clientlist[connection]=address
                    self.count+=1
#             print self.clientlist,self.count
#             self.chatText.insert(END, str(address)+'服务器端已经与客户端建立连接......\n')
            if self.clientlist:
                self.flag = True
#             self.connection.settimeout(5)
            start_new_thread(messagehandle ,(self.clientlist,connection,address))
        self.ServerSock.close() 
    def startNewThread(self):
        thread1 = threading.Timer(1, self.receiveMessage)
        thread1.setDaemon(True)
        thread1.start() 

if __name__=="__main__":
    root = tk.Tk()
    root.title("Server")
    root.resizable(False,False)
    app = Application(master=root)
    app.startNewThread()
    app.mainloop()
